/*--------------------------------------------------------------------------
Modified from GNU Group's SDCC
Only for study purpose
---------------------------------------------------------------------------*/

#ifndef __COMPILER_GROUP_VALUE_H
#define __COMPILER_GROUP_VALUE_H

#include "SymbolTable.h"

/* double to unsigned long conversion */
/*
 * See ISO/IEC 9899, chapter 6.3.1.4 Real floating and integer:
 * If the value of the integral part cannot be represented by the integer type, the behavior is undefined.
 * This shows up on Mac OS X i386 platform which useus SSE unit instead of the x87 FPU for floating-point operations
 */
/*
 * on Mac OS X ppc (long) 2147483648.0 equals to 2147483647, so we explicitely convert it to 0x80000000
 * on other known platforms (long) 2147483648.0 equals to -2147483648
 */
#define double2ul(val)  (((val) < 0) ? (((val) < -2147483647.0) ? 0x80000000UL : (unsigned long) -((long) -(val))) : (unsigned long) (val))

/* value wrapper */
typedef struct value
{
	char name[MAX_NAME + 1]; /* operand accessing this value     */
	sym_link *type;               /* start of type chain              */
	sym_link *etype;              /* end of type chain                */
	symbol *sym;                  /* Original Symbol                  */
	struct value *next;           /* used in initializer list         */
	unsigned vArgs:1;             /* arg list ended with variable arg */
} value;

#define  IS_VARG(x)             (x->vArgs)

/* forward definitions for the symbol table related functions */
value *newValue (void);
unsigned long ulFromVal (value *);
sym_link * computeType (sym_link *, sym_link *, int);
value *valFromType (sym_link *);
value *constVal (const char *);
value *constCharVal (unsigned char);
value *charVal (const char *s);
value *valueFromLit (long);
value *valComplement (value *);
value *valNot (value *);
value *valMult (value *, value *);
value *valDiv (value *, value *);
value *valMod (value *, value *);
value *valPlus (value *, value *);
value *valMinus (value *, value *);
value *valShift (value *, value *, int);
value *valBitwise (value *, value *, int);
value *valLogicAndOr (value *, value *, int);
value *valCastLiteral (sym_link *, double);
value *symbolVal (symbol *);
value *reverseVal (value *);

#endif